package com.yoyo.yyadsdk.util;

import android.annotation.NonNull;
import android.app.ActivityManager;
import android.app.PackageInstallObserver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
import android.os.Environment;
import android.text.TextUtils;

import com.yoyo.yyadsdk.open.MyPackageInstallObserver;
import com.yoyo.yyadsdk.open.MyPackageInstallObserver2;

import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;

public class ActivityUtils {

    /**
     * 通过判断手机里的所有进程是否有这个App的进程
     * 从而判断该App是否有打开
     */
    public static boolean appIsRunning(Context context, String mainProcessName) {
        //通过ActivityManager我们可以获得系统里正在运行的activities
        //包括进程(Process)等、应用程序/包、服务(Service)、任务(Task)信息。
        ActivityManager am = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE));
        List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();
        //利用一个增强for循环取出手机里的所有进程
        for (ActivityManager.RunningAppProcessInfo info : processInfos) {
            //通过比较进程的唯一标识和包名判断进程里是否存在该App
            if (mainProcessName.equals(info.processName)) {
                return true;
            }
        }
        return false;
    }

    public static boolean isAppInstalled(Context context, String pkgName) {
        if (pkgName == null || pkgName.isEmpty())
            return false;
        try {
            return context.getPackageManager().getPackageInfo(pkgName, PackageManager.GET_ACTIVITIES) != null;
        } catch (PackageManager.NameNotFoundException e) {
            return false;
        }
    }

    @NonNull
    public static String getAppInfoByUid(Context context, int uid) {
        PackageManager pm = context.getPackageManager();
        List<ApplicationInfo> installedApplications = pm.getInstalledApplications(PackageManager.GET_ACTIVITIES);
        for (ApplicationInfo a : installedApplications) {
            if (a.uid == uid) return a.packageName;
        }
        return "";
    }

    /**
     * 根据包名杀死对应进程
     */
    public static void killBackgroundProcesses(Context context, String packageName) {
        //通过ActivityManager我们可以获得系统里正在运行的activities
        //包括进程(Process)等、应用程序/包、服务(Service)、任务(Task)信息。
        ActivityManager am = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE));
        am.killBackgroundProcesses(packageName);
//        ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE)).forceStopPackage(packageName);
        LogHelper.e("killBackgroundProcesses:" + packageName);
    }

    /**
     * 程序是否在前台运行
     */
    public static boolean isAppOnForeground(Context context, String packageName) {
        // Returns a list of application processes that are running on the device
        ActivityManager am = ((ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE));
        List<ActivityManager.RunningAppProcessInfo> processInfos = am.getRunningAppProcesses();
        if (processInfos == null) return false;
        for (ActivityManager.RunningAppProcessInfo appProcess : processInfos) {
            // The name of the process that this object is associated with.
            if (appProcess.processName.equals(packageName)
                    && appProcess.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
                return true;
            }
        }
        return false;
    }

    /**
     * 静默卸载
     */
    public static void uninstallApkDefaul(Context context, String action,
                                          String packageName) {
//        PackageManager pm = context.getPackageManager();
//        IPackageDeleteObserver observer = new MyPackageDeleteObserver(context, action, packageName);
//        context.getPackageManager().deletePackage(packageName, observer, 0);
    }

    /**
     * 静默安装
     */
    public static void autoInstallApk(Context context, String fileName, String packageName) {
        File file = new File(fileName);
        int installFlags = 0;
        if (!file.exists())
            return;
        installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
        if (hasSdcard()) {
            installFlags |= PackageManager.INSTALL_EXTERNAL;
        }
        try {
            context.getPackageManager().installPackage(Uri.fromFile(file), new MyPackageInstallObserver(context), installFlags,
                    packageName);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断有无sd卡
     */
    public static boolean hasSdcard() {
        String status = Environment.getExternalStorageState();
        if (status.equals(Environment.MEDIA_MOUNTED)
                || status.equals("/mnt/sdcard")) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 静默安装
     */
    public static void autoInstallApk(Context context, File file, String packageName) {
        if (Build.VERSION.SDK_INT > 23) {
            installApkInSilence(context,file.getAbsolutePath(), packageName);
        } else {
            PackageManager packageManager = context.getPackageManager();
            Class<?> pmClz = packageManager.getClass();
//            Class<?> aClass;
            try {
//                aClass = Class.forName("android.app.PackageInstallObserver");
//                Constructor<?> constructor;
//                constructor = aClass.getDeclaredConstructor();
//                constructor.setAccessible(true);
//                Object installObserver;
//                installObserver = constructor.newInstance();
                Method method;
                method = pmClz.getDeclaredMethod("installPackage", Uri.class, PackageInstallObserver.class, int.class, String.class);
                method.setAccessible(true);
                method.invoke(packageManager, Uri.fromFile(file), new MyPackageInstallObserver(context), 2, null);
//            } catch (ClassNotFoundException e) {
//                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
//            } catch (InstantiationException e) {
//                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * void installPackageAsUser(in String originPath,
     * in IPackageInstallObserver2 observer,
     * int flags,
     * in String installerPackageName,
     * int userId);
     *
     */
    private static void installApkInSilence(Context context,String installPath, String packageName) {
//            IPackageManager mPm = IPackageManager.Stub.asInterface(ServiceManager.getService("package"));
//            try {
//                mPm.installPackageAsUser(Uri.fromFile(file).getPath(), new MyPackageInstallObserver2(), 2, file.getName(), context.getUserId());
//            } catch (RemoteException e) {
//                e.printStackTrace();
//            }
        Class<?> pmService;
        Class<?> activityTherad;
        Method method;
        try {
            activityTherad = Class.forName("android.app.ActivityThread");
            Class<?>[] paramTypes = getParamTypes(activityTherad, "getPackageManager");
            method = activityTherad.getMethod("getPackageManager", paramTypes);
            Object PackageManagerService = method.invoke(activityTherad);
            pmService = PackageManagerService.getClass();
            Class<?>[] paramTypes1 = getParamTypes(pmService, "installPackageAsUser");
            method = pmService.getMethod("installPackageAsUser", paramTypes1);
            method.invoke(PackageManagerService, installPath, new MyPackageInstallObserver2(context), 0x00000040, packageName, getUserId(Binder.getCallingUid()));//getUserId
//            method.invoke(PackageManagerService, installPath, null, 0x00000040, packageName, getUserId(Binder.getCallingUid()));//getUserId
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    private static Class<?>[] getParamTypes(Class<?> cls, String mName) {
        Class<?>[] cs = null;
        Method[] mtd = cls.getMethods();
        for (Method method : mtd) {
            if (!method.getName().equals(mName)) {
                continue;
            }
            cs = method.getParameterTypes();
        }
        return cs;
    }

    private static final int PER_USER_RANGE = 100000;

    private static int getUserId(int uid) {
        return uid / PER_USER_RANGE;
    }

    /**
     * 根据包名获取上下文
     */
    public static Context getPackageContext(Context context, String packageName) {
        Context pkgContext = null;
        if (context.getPackageName().equals(packageName)) {
            pkgContext = context;
        } else {
            // 创建第三方应用的上下文环境
            try {
                pkgContext = context.createPackageContext(packageName,
                        Context.CONTEXT_IGNORE_SECURITY
                                | Context.CONTEXT_INCLUDE_CODE);
            } catch (PackageManager.NameNotFoundException e) {
                e.printStackTrace();
            }
        }
        return pkgContext;
    }

    /**
     * 根据包名打开应用
     */
    public static boolean openPackage(Context context, String packageName) {
        Context pkgContext = getPackageContext(context, packageName);
        Intent intent = getAppOpenIntentByPackageName(context, packageName);
        if (pkgContext != null && intent != null) {
            pkgContext.startActivity(intent);
            return true;
        }
        return false;
    }

    /**
     * 根据包名获取打开应用的Intent
     */
    public static Intent getAppOpenIntentByPackageName(Context context, String packageName) {
        // MainActivity完整名
        String mainAct = null;
        // 根据包名寻找MainActivity
        PackageManager pkgMag = context.getPackageManager();
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);
        intent.setFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED | Intent.FLAG_ACTIVITY_NEW_TASK);

//        List<ResolveInfo> list = pkgMag.queryIntentActivities(intent, PackageManager.GET_ACTIVITIES);
        List<ResolveInfo> list = pkgMag.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
        for (int i = 0; i < list.size(); i++) {
            ResolveInfo info = list.get(i);
            if (info.activityInfo.packageName.equals(packageName)) {
                mainAct = info.activityInfo.name;
                break;
            }
        }
        if (mainAct == null || TextUtils.isEmpty(mainAct)) {
            return null;
        }
        intent.setComponent(new ComponentName(packageName, mainAct));
        return intent;
    }

    public static String getProcessName(Context cxt, int pid) {
        //获取ActivityManager对象
        ActivityManager am = (ActivityManager) cxt.getSystemService(Context.ACTIVITY_SERVICE);
        //在运行的进程的
        List<ActivityManager.RunningAppProcessInfo> runningApps = am.getRunningAppProcesses();
        if (runningApps == null) {
            return null;
        }
        for (ActivityManager.RunningAppProcessInfo procInfo : runningApps) {
            if (procInfo.pid == pid) {
                return procInfo.processName;
            }
        }
        return null;
    }
}
